home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / fragment.zip / COALESCE.C next >
C/C++ Source or Header  |  1988-01-21  |  6KB  |  211 lines

  1. /*
  2.  * coalesce.c  -- program to coalesce several files into one file.  Reverse
  3.  *                   of the fragment program.  Together these two programs
  4.  *                   allow the user to transport files larger than the drives
  5.  *             of the involved machines.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10.  
  11. long filelength(int) ;            /* Wasn't declared in <stdio.h> ! */
  12.  
  13. #define    TRUE    1
  14. #define FALSE    0
  15.  
  16. #define    DISK_SIZE_DESIRED    327680L
  17. #define CHUNK_SIZE        16384
  18. #define    MAX_FNAME_LEN        256
  19.  
  20. char buffer[CHUNK_SIZE] ;
  21. int prompt = FALSE ;
  22. char in_path[MAX_FNAME_LEN+1] ;
  23. char in_template[MAX_FNAME_LEN+1] ;
  24.  
  25. void prompt_for_new_file(fragment_nbr)
  26. int fragment_nbr ;
  27. {
  28.     fprintf(stderr, "Strike any key when ready with Fragment %0d.", fragment_nbr) ;
  29.     fflush(stderr) ;
  30.     fflush(stdin) ;
  31.     getch() ;
  32. }
  33.  
  34. FILE *next_input_file(in_template, suffix_ndx, fragment_nbr)
  35. char *in_template ;
  36. int suffix_ndx ;
  37. int fragment_nbr ;
  38. {
  39.     char suffix[3+1] ;
  40.  
  41.     sprintf(suffix, "%0d", 100+fragment_nbr) ;
  42.     strncpy(&in_template[suffix_ndx], &suffix[1], 2) ;
  43.  
  44.     return fopen(in_template, "rb") ;
  45. }
  46.  
  47. void coalesce(big_stream, in_template, suffix_ndx)
  48. FILE *big_stream ;
  49. char *in_template ;
  50. int   suffix_ndx ;
  51. {
  52.     long  bytes_written ;
  53.     FILE *in_stream ;
  54.     int   byte_cnt ;
  55.     int   fragment_nbr ;
  56.     int   chunk ;
  57.  
  58.     bytes_written = 0L ;
  59.     for (fragment_nbr=0; fragment_nbr < 100; fragment_nbr++) {
  60.  
  61.     if (prompt)
  62.         prompt_for_new_file(fragment_nbr) ;
  63.  
  64.     in_stream = next_input_file(in_template, suffix_ndx, fragment_nbr) ;
  65.     if (in_stream == NULL)
  66.         break ;
  67.  
  68.     for (chunk=0; chunk < DISK_SIZE_DESIRED/CHUNK_SIZE; chunk++) {
  69.         byte_cnt = fread(buffer, 1, CHUNK_SIZE, in_stream) ;
  70.         if (byte_cnt == 0)
  71.         break ;
  72.         fprintf(stderr, "\rFragment %2d, Chunk %2d: %0d bytes Read     ",
  73.             fragment_nbr, chunk, byte_cnt) ;
  74.         fflush(stderr) ;
  75.         if (fwrite(buffer, 1, byte_cnt, big_stream) != byte_cnt) {
  76.         fprintf(stderr, "\n") ;
  77.         fprintf(stderr, "Error Writing Fragment %2d, Chunk %2d.\n") ;
  78.         fprintf(stderr, "Total of %0ld were successfully coalesced.\n",
  79.                 bytes_written) ;
  80.         exit(1) ;
  81.         }
  82.         bytes_written += (long)byte_cnt ;
  83.         fprintf(stderr, "\rFragment %2d, Chunk %2d: %0d bytes Written    ",
  84.             fragment_nbr, chunk, byte_cnt) ;
  85.         fflush(stderr) ;
  86.     }
  87.  
  88.     fclose(in_stream) ;
  89.     fprintf(stderr, "\rFragment %2d: Coalesced                                     \n", fragment_nbr) ;
  90.     }
  91.  
  92.     fclose(big_stream) ;
  93.     fprintf(stderr, "Coalescing complete.  %0d fragments were read, totally %0ld bytes\n",
  94.         fragment_nbr, bytes_written) ;
  95. }
  96.  
  97. void get_template(file_template, in_template, suffix_ndx)
  98. char *file_template ;
  99. char *in_template ;
  100. int  *suffix_ndx ;
  101. {
  102.     char fname_template[8+1] ;
  103.     char file_ext[1+3+1] ;
  104.     char *file_name ;
  105.     char *file_dot ;
  106.  
  107.     *in_path = '\0' ;
  108.     file_name = file_template ;
  109.     if (strchr(file_template, '\\') || strchr(file_template, ':')) {
  110.     if (strchr(file_template, '\\'))
  111.         file_name = strrchr(file_template, '\\')+1 ;
  112.         else
  113.         file_name = strrchr(file_template, ':')+1 ;
  114.     if (file_name-file_template > MAX_FNAME_LEN) {
  115.         fprintf(stderr, "Directory path of %s is too long.\n", file_template) ;
  116.         exit(1) ;
  117.     } else {
  118.         strncpy(in_path, file_template, file_name-file_template) ;
  119.         in_path[file_name-file_template+1] = '\0' ;
  120.     }
  121.     }
  122.  
  123.     *file_ext = '\0' ;
  124.     file_dot = strchr(file_name, '.') ;
  125.     if (file_dot)
  126.     if (strlen(file_dot) > 4) {
  127.         fprintf(stderr, "The extension of '%s' is too long.\n", file_dot) ;
  128.         exit(1) ;
  129.     } else {
  130.         strcpy(file_ext, file_dot) ;
  131.         *file_dot = '\0' ;
  132.     }
  133.  
  134.     strcpy(fname_template, "________") ;
  135.     if (strlen(file_name) > 6) {
  136.     fprintf(stderr, "The filename of '%s' is too long.\n", file_name) ;
  137.     exit(1) ;
  138.     }
  139.     strncpy(fname_template, file_name, strlen(file_name)) ;
  140.  
  141.     if (strlen(in_path)+strlen(fname_template)+strlen(file_ext) > MAX_FNAME_LEN) {
  142.     fprintf("The resulting input pathname of '%s%s%s' is too long.\n",
  143.            in_path, fname_template,file_ext) ;
  144.     exit(1) ;
  145.     }
  146.  
  147.     strcpy(in_template, in_path) ;
  148.     strcat(in_template, fname_template) ;
  149.     *suffix_ndx = strlen(in_template) - 2 ;
  150.     strcat(in_template, file_ext) ;
  151. }
  152.  
  153. void main(argc, argv)
  154. int argc ;
  155. char *argv[] ;
  156. {
  157.     FILE *big_stream ;
  158.     long  length ;
  159.     int   suffix_ndx ;
  160.  
  161.     argc-- ; /* throw away "program name" argument */
  162.     argv++ ;
  163.  
  164.     /* parse off any "prompt option" argument that is present */
  165.  
  166.     prompt = FALSE ;
  167.     if (argc && (stricmp(argv[0], "-p") == 0)) {
  168.     argc-- ;
  169.     argv++ ;
  170.     prompt = TRUE ;
  171.     }
  172.  
  173.     if ((argc != 2) || (*argv[0] == '?')) {
  174.     fprintf(stderr, "\n") ;
  175.     fprintf(stderr, "   coalesce [-p] <big fname> <input file template>\n") ;
  176.     fprintf(stderr, "\n") ;
  177.     fprintf(stderr, "   Where:\n") ;
  178.     fprintf(stderr, "\n") ;
  179.     fprintf(stderr, "       -p optionally causes the program to pause between input files.\n") ;
  180.     fprintf(stderr, "           (allowing you to, say, change input disks)\n") ;
  181.     fprintf(stderr, "       <big fname> is the full pathname to the file to be coalesced.\n") ;
  182.     fprintf(stderr, "       <input file template> is the path to the input directory\n") ;
  183.     fprintf(stderr, "          along with a six letter filename template which will\n") ;
  184.     fprintf(stderr, "          be suffixed with the fragment nbr and the extension.\n") ;
  185.     fprintf(stderr, "\n") ;
  186.     fprintf(stderr, "   Example:\n") ;
  187.     fprintf(stderr, "\n") ;
  188.     fprintf(stderr, "       coalesce -p c:\\pcip\\src\\doc.tar a:doc.frg\n") ;
  189.     fprintf(stderr, "\n") ;
  190.     fprintf(stderr, "       Coalesces the file c:\\pcip\\src\\doc.tar from the\n") ;
  191.     fprintf(stderr, "          fragments named a:doc___00.frg, a:doc___01.frg, etc.\n") ;
  192.     fprintf(stderr, "       Since -p is present, the program will pause between each file.\n") ;
  193.     exit(1) ;
  194.     }
  195.  
  196.     if ((big_stream = fopen(argv[0], "rb")) != NULL) {
  197.     fprintf(stderr, "The output file '%s' already exists.\n", argv[0]) ;
  198.     fprintf(stderr, "   Hit Ctrl-Break to abort, any other key to overwrite.\n") ;
  199.     getch() ;
  200.     fclose(big_stream) ;
  201.     }
  202.     if ((big_stream = fopen(argv[0], "wb")) == NULL) {
  203.     fprintf(stderr, "can't open %s for input.\n", argv[0]) ;
  204.     exit(1) ;
  205.     }
  206.  
  207.     get_template(argv[1], in_template, &suffix_ndx) ;
  208.  
  209.     coalesce(big_stream, in_template, suffix_ndx) ;
  210. }
  211.